package twoD.IsoPfem;

import inf.jlinalg.SolveFailedException;
import inf.v3d.obj.Sphere;
import inf.v3d.view.Viewer;
import twoD.IsoPfem.Control.ArcLengthController;
import twoD.IsoPfem.Control.DisplacementConstraintCondition;
import twoD.IsoPfem.Control.IConstraintCondition;
import twoD.IsoPfem.Control.LoadConstraintCondition;
import twoD.IsoPfem.Control.SphereConstraintCondition;
import twoD.IsoPfem.math.FunctionRToR;
import twoD.IsoPfem.math.Interval;

/**
 * Perforated plate.
 * 
 * @author Bui Hoang Giang
 */
public class PerforatedPlateDemo {

	public static void main(String[] args) {
		// new PerforatedPlate().testStaticEquilibrium();
		new PerforatedPlateDemo().testControl3();
	}

	public void testStaticEquilibrium() {
		ElasticStructure struct = new PerforatedPlateDemo().createModel();

		struct.solveLinearStaticEquilibrium();
		struct.listingDisplacements();

		Viewer view = new Viewer();
		Visualizer viz = new Visualizer(struct, view);
		double d_max = viz.automaticScale();
		viz.drawConstraints();
		viz.drawForces();
		viz.drawEdgeLoads();
		// viz.drawElements();

		viz.postAutomaticScale(d_max);
		viz.drawDisplacedStructure();
		viz.drawSigma11();

		view.setVisible(true);
	}

	public void testControl1() {
		ElasticStructure struct = new PerforatedPlateDemo().createModel();
		IConstraintCondition cc = new LoadConstraintCondition(1, 0.1);
		ArcLengthController C = new ArcLengthController(struct, cc);
		C.setNumberOfStep(10);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		C.listingState();
	}

	public void testControl2() {
		ElasticStructure struct = new PerforatedPlateDemo().createModel();
		IConstraintCondition cc = new DisplacementConstraintCondition(10, 0.1,
				0);
		ArcLengthController C = new ArcLengthController(struct, cc);
		C.setNumberOfStep(2);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		C.listingState();
	}

	public void testControl3() {
		ElasticStructure struct = new PerforatedPlateDemo().createModel();
		IConstraintCondition cc = new SphereConstraintCondition(1, 0, 0);
		ArcLengthController C = new ArcLengthController(struct, cc);
		C.setNumberOfStep(2);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		C.listingState();
	}

	public ElasticStructure createModel() {
		Mesh M = new Mesh();

		// nodes
		Node n0 = M.addNode(new Node((-100), 0));
		Node n1 = M.addNode(new Node((-30), 0));
		Node n2 = M.addNode(new Node((-10), 0));
		Node n3 = M
				.addNode(new Node((-10 / Math.sqrt(2)), (10 / Math.sqrt(2))));
		Node n4 = M.addNode(new Node(0, 10));
		Node n5 = M.addNode(new Node((-20), 20));
		Node n6 = M.addNode(new Node(0, 30));
		Node n7 = M.addNode(new Node((-100), 100));
		Node n8 = M.addNode(new Node(0, 100));

		// geometries
		Triangle t0 = new Triangle(n0, n1, n5);
		Triangle t1 = new Triangle(n0, n5, n7);
		Triangle t2 = new Triangle(n7, n5, n8);
		Triangle t3 = new Triangle(n5, n6, n8);
		Triangle t4 = new Triangle(n1, n3, n5);
		Triangle t5 = new Triangle(n1, n2, n3);
		Triangle t6 = new Triangle(n3, n4, n6);
		Triangle t7 = new Triangle(n3, n6, n5);
		M.addGeometry(t0);
		M.addGeometry(t1);
		M.addGeometry(t2);
		M.addGeometry(t3);
		M.addGeometry(t4);
		M.addGeometry(t5);
		M.addGeometry(t6);
		M.addGeometry(t7);

		ElasticStructure struct = new ElasticStructure(M);
		RealTable realTable = new RealTable(206900, 0.29);
		realTable.setThickness(0.1);

		// elements
		for (IGeometry g : M.getGeometries()) {
			struct.addElement(new CST(realTable, g));
		}
		IElement e2 = struct.getElements(t2);

		// constraints u_2 = 0
		Constraint c1 = new Constraint(true, false);
		n0.setConstraint(c1);
		n1.setConstraint(c1);
		n2.setConstraint(c1);

		// constraints u_1 = 0
		Constraint c2 = new Constraint(false, true);
		n4.setConstraint(c2);
		n6.setConstraint(c2);
		n8.setConstraint(c2);

		// vertical load
		// EdgeLoad el = new EdgeLoad(e11, null, new PolynomialRToR(-1.0, 1.0,
		// 100.0));
		// struct.addLoad(el);

		// Force f = new Force(0, 100);
		// n7.setForce(f);
		// n8.setForce(f);

		EdgeLoad el = new EdgeLoad(n7, n8, new FunctionRToR() {

			@Override
			public double valueAt(double x) {
				return -500;
			}

			@Override
			public int getP() {
				return 0;
			}

			@Override
			public Interval getDomain() {
				return new Interval(0, 1);
			}

			@Override
			public double[] getBreakpoints() {
				return null;
			}

			@Override
			public double derivativeAt(double x) {
				return 0;
			}
		});

		e2.addEdgeLoad(el);

		return struct;
	}

	public String getDescription() {
		// you can put html code here
		return "A perforated plate. <i>Contributed by:</i> Matthias Baitsch";
	}
}
